//author: create by SunJH
//时间: 2021/11/22 0022
//邮箱: 965989158@qq.com
//描述: 网络请求管理器，在这里统一处理，封装网络请求

import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:cookie_jar/cookie_jar.dart';

import 'http_config.dart';
import 'interceptors/my_log_interceptor.dart';
import 'interceptors/token_interceptor.dart';
import 'result_bean.dart';


/**
 * TODO 针对某个网络请求，不使用通用的域名，域名从url传入使用，但是不能影响其他网络请求使用通用域名。
 */
class HttpUtil {
  static  final HttpUtil _instance = HttpUtil._();
  static HttpUtil getInstance() => _instance;
  HttpUtil._();

  TokenInterceptors? _tokenInterceptors;
  var decode = json.decode(r'{"msg":"网络请求错误","code":-1}');
  final Dio _dio = Dio();

  proInit(HttpConfig httpConfig) {
    _dio.options.baseUrl = httpConfig.baseUrl;
    _dio.options.connectTimeout = httpConfig.kConnectTimeout;
    _dio.options.receiveTimeout = httpConfig.kReceiveTimeout;
    _dio.options.sendTimeout = httpConfig.kSendTimeout;
    _dio.interceptors.add(MyLogInterceptor(httpConfig.isShowLog));
  }

  Dio get client => _dio;

  void setToken(String token){
    _tokenInterceptors = TokenInterceptors(token);
    _dio.interceptors.add(_tokenInterceptors!);
  }

  /**
   * 给网络请求添加cookie，并让后续网络请求自动管理cookie
   */
  void setCookie(Cookie cookie){
    var cookieManager = CookieManager(CookieJar());
    _dio.interceptors.add(cookieManager);

    Map<String,dynamic> headers = {};
    headers["Cookie"] = cookie;
    client.options.headers = headers;
  }

  void deleteToken(){
    _dio.interceptors.remove(_tokenInterceptors);
  }

  void rebase(String baseIp) {
    _dio.options.baseUrl = baseIp;
  }

  Future<ResultBean<T?>> get<T>(String url,
      { JsonParse<T>? jsonParse, Map<String, dynamic>? params}) async {
    String? errorMsg;
    Response response;
    try{
      response = await _dio.get(url, queryParameters: params);
    }on DioError catch(e){
      print(e.toString());
      return ResultBean.error(decode);
    }
    if (errorMsg != null ) {
      return ResultBean.error(decode);
    }
   return _transformData(response,jsonParse);
  }

  Future<ResultBean<T?>> post<T>(String url,
      { JsonParse<T>? jsonParse, Map<String, dynamic>? params}) async {
    String? errorMsg;
    Response response;
    try{
      response = await _dio.post(url, data: params);
    }on DioError catch(e){
      print(e.toString());
      return ResultBean.error(decode);
    }
    if (errorMsg != null ) {
      return ResultBean.error(decode);
    }
    return _transformData(response,jsonParse);
  }

  ResultBean<T> _transformData<T>(Response response, JsonParse<T>? jsonParse){
    //TODO 需要外部配置统一请求错误码
    switch (response.data['code']) {
      case 200:
        return ResultBean.fromData(response.data, jsonParse);
      case 401:{
        // token 过期，需要跳转到登录页面
        return ResultBean.error(response.data);
      }
      default:
        return ResultBean.error(response.data);
    }
  }
}
